# -*- coding: UTF8 -*-
# Author: Sakurazaki
# (Aitor Martin. @arienai_ne - sakurazaki.setsunita@gmail.com)

# STD
from random import random, randint
from math import sin, cos, radians

# Pygame
import pygame.transform

# Project
from entity import Entity, State
from imageloader import getCircle, loadImage


class Island(Entity):

    name = "Island"

    def __init__(self, team, prop):

        # Load Entity
        super(Island, self).__init__(team + "_" + prop['texture'])
        self.font = pygame.font.SysFont("Arial", 22)

        # Behaviour
        self.state = State.GROW
        self.team = team

        # Health
        self.MIN_BUBBLES = 0.0
        self.MAX_BUBBLES = prop['max_bubbles']
        self.bubbles = round(random() * self.MAX_BUBBLES, 2)

        # Grow
        self.growth = prop['growth'] # How many bubbles per increase tick
        self.next_growth = 0.0 # Time for next growth tick
        
        self.growth_rate = prop['growth_rate'] # How much growth will increase
        self.last_increased = 0.0
        
        self.keep_growing = True # Determine if growth_rate can increase
        self.TIME_TO_GROW = prop['time_to_grow']
        self.TIME_TO_INCREASE = prop['time_to_increase']
        self.MIN_GROWTH = prop['min_growth'] #bps (bubble per second)
        self.MAX_GROWTH = prop['max_growth'] # bps
        
        # Decay
        self.decay = prop['decay']
        self.next_decay = 0.0

        self.decay_rate = prop['decay_rate']
        self.last_decreased = 0.0
        
        self.keep_decaying = True
        self.TIME_TO_DECAY = prop['time_to_decay']
        self.TIME_TO_DECREASE = prop['time_to_decrease']
        self.MIN_DECAY = prop['min_decay']
        self.MAX_DECAY = prop['max_decay'] #bps

        # Idle
        self.switchedToIdle = 0.0
        self.TIME_TO_SWITCH = prop['time_to_switch']

        # Size
        self.MIN_RADIUS = prop['min_radius']
        self.MAX_RADIUS = prop['max_radius']

        # Game vars
        self.radius = (self.bubbles * (self.MAX_RADIUS - self.MIN_RADIUS) / self.MAX_BUBBLES) + self.MIN_RADIUS
        if self.radius <= self.MIN_RADIUS:
            self.radius = self.MIN_RADIUS
        elif self.radius >= self.MAX_RADIUS:
            self.radius = self.MAX_RADIUS
        self.size = 0.5 + self.radius / 110

        # First surface init
        self.scale()
        self.rect = self.surface.get_rect()
        self.rect.center = self.pos.get()

    def update(self, delta):

        if self.state == State.IDLE:

            # Check decay time
            self.switchedToIdle += delta
            if self.switchedToIdle >= self.TIME_TO_SWITCH:
                self.state = State.DECAY
                self.decayrate = 1.0
                self.switchedToIdle = 0.0

        elif self.state == State.GROW:

            # Update quantity
            self.next_growth += delta
            if self.next_growth >= self.TIME_TO_GROW:
                self.bubbles += self.growth
                self.next_growth = 0.0

            if self.bubbles >= self.MAX_BUBBLES:
                self.bubbles = self.MAX_BUBBLES
                self.growth = self.MIN_GROWTH
                self.next_growth = 0.0
                self.last_increased = 0.0
                self.state = State.IDLE

            # Update growth rate
            self.last_increased += delta
            if self.keep_growing and self.last_increased >= self.TIME_TO_INCREASE:
                self.growth += self.growth_rate
                self.last_increased = 0.0

                if self.growth >= self.MAX_GROWTH:
                    self.growth = self.MAX_GROWTH
                    self.keep_growing = False

        elif self.state == State.DECAY:

            # Update quantity
            self.next_decay += delta
            if self.next_decay >= self.TIME_TO_DECAY:
                self.bubbles -= self.decay
                self.next_decay = 0.0

            if self.bubbles <= self.MIN_BUBBLES:
                self.bubbles = self.MIN_BUBBLES
                self.decay = self.MIN_DECAY
                self.next_decay = 0.0
                self.last_decreased = 0.0
                self.state = State.GROW

            # Update decay rate
            self.last_decreased += delta
            if self.keep_decaying and self.last_decreased >= self.TIME_TO_DECREASE:
                self.decay += self.decay_rate
                self.last_decreased = 0.0

                if self.decay >= self.MAX_DECAY:
                    self.decay = self.MAX_DECAY
                    self.keep_decaying = False

        # Afterwards calculations

        # New Radius
        self.radius = (self.bubbles * (self.MAX_RADIUS - self.MIN_RADIUS) / self.MAX_BUBBLES) + self.MIN_RADIUS
        if self.radius <= self.MIN_RADIUS:
            self.radius = self.MIN_RADIUS
        elif self.radius >= self.MAX_RADIUS:
            self.radius = self.MAX_RADIUS
        self.size = 0.5 + self.radius / 150

    def render(self):

        self.surface = self.image
        self.scale()
        self.rect = self.surface.get_rect()
        self.rect.center = self.pos.get()

        fontsurf = self.font.render(str(int(self.bubbles)), True, pygame.Color('White'))
        fontrect = fontsurf.get_rect()
        fontrect.center = (self.surface.get_width()/2, self.surface.get_height()/2)
        self.surface.blit(fontsurf, fontrect)

    def __repr__(self):
        return "%s Island at %s" % (self.team, self.pos)

class Bubble(Entity):

    name = "Bubble"

    PI = 3.141518

    def __init__(self, island, prop):

        # Entity init
        super(Bubble, self).__init__(island.team + "_" + prop['texture'])

        # Property of
        self.island = island

        # Behaviour
        self.state = State.FLOAT

        # Move State
        self.speed = prop['speed']

        # Position
        self.angle = 0.0
        self.setPosition(self.island.pos.x + cos(radians(self.angle)) * (self.island.surface.get_width() + 15),
        self.island.pos.y + sin(radians(self.angle)) * (self.island.surface.get_height() + 15))

    def update(self, delta):

        if self.state == State.FLOAT:

            self.angle += delta / self.speed
            if self.angle >= 359:
                self.angle = 0.0
            
            self.setPosition(self.island.pos.x + cos(radians(self.angle)) * (self.island.radius + 15),
            self.island.pos.y + sin(radians(self.angle)) * (self.island.radius + 15))

    def render(self):
        self.rect = self.surface.get_rect()
        self.rect.center = self.pos.get()
